#pragma once


#include <iostream>
#include <memory>
#include "Epoller.hpp"
#include "InetAddr.hpp"
#include "Socket.hpp"
#include "Log.hpp"
#include "Connection.hpp"
#include "IOService.hpp"
#include "Reactor.hpp"
#include "Protocol.hpp"
#include "Calculator.hpp"

using namespace SocketModule;
using namespace LogModule;


//专门获取链接的模块
class Listener : public Connection
{
public:
    Listener(int port)
    :_listensock(std::make_unique<TcpSocket>()),
    _port(port)
    {
        _listensock->BuildTcpSocketMethod(_port);

        SetSockfd(_listensock->Fd());

        SetEvents(EPOLLIN|EPOLLET);

    }

    virtual void Recver() override
    {
        //读事件就绪,就是listensock就绪
        //IO处理 -- 获取新连接
        LOG(LogLevel::INFO) << "Recver" ;
        while(true)
        {
            InetAddr peer;
            int aerrno = 0;
            int sockfd = _listensock->Accepter(&peer,&aerrno);
            if(sockfd > 0)
            {
                //success
                //我们毫不意外是不能直接读取的!
                //sockfd 要添加到 epoll中 
                //epollserver只认connection
                LOG(LogLevel::DEBUG) << "Accepter success: "<<sockfd;
                //普通的文件描述符,也是处理IO的,也是connection!

                //1.设置文件描述符非阻塞
                SetNonBlock(sockfd);
                //2.sockfd包装成为Connection!
                auto conn = std::make_shared<IOServer>(sockfd);
                conn->RegisterOnMessage(HandlerRequest);
                //3.插入到EpollServer中
                GetOwner()->InsertConnection(conn);
                //设置好之后,就没了,等待下一次LoopOnce检测事件的发生
            }
            else
            {
                if(aerrno == EAGAIN || aerrno == EWOULDBLOCK)
                {
                    LOG(LogLevel::DEBUG) << "accepter all connection... done";
                    break;
                }
                else if(aerrno == EINTR)
                {
                    //信号中断
                    LOG(LogLevel::DEBUG) << "accepter intr by signal, continue";
                    continue;
                }
                else
                {
                    LOG(LogLevel::DEBUG) << "accepter error ... ignore";
                    break;
                }
            }
        }
    }
    virtual void Sender() override
    {
        //
    }
    virtual void Excepter() override
    {
        //
    }

    int Socketfd()
    {
        return _listensock->Fd();
    }
    ~Listener()
    {
        _listensock->Close();
    }
private:
    std::unique_ptr<Socket> _listensock;
    int _port;
};

